package org.aaa.cycicbarrior;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierTest {
    private CyclicBarrier cyclicBarrier;

    private List<UserConsumeInfo> partialResults = new CopyOnWriteArrayList<>();
    private Random random = new Random();
    private List<Integer> years;
    private List<String> users;

    public CyclicBarrierTest(List<Integer> years, List<String> users) {
        this.years = years;
        this.users = users;
    }

    public void startCalc() {
        cyclicBarrier = new CyclicBarrier(users.size(), new AggregatorThread());
        for (int i = 0; i < users.size(); i++) {
            Thread worker = new Thread(new CalcUserAmountThread(users.get(i)));
            worker.setName(users.get(i));
            worker.start();
        }
    }

    final class CalcUserAmountThread implements Runnable {
        private String username;

        public CalcUserAmountThread(String username) {
            this.username = username;
        }

        @Override
        public void run() {
            UserConsumeInfo userConsumeInfo = new UserConsumeInfo();
            userConsumeInfo.setUsername(username);
            ArrayList<UserAggreInfo> userAggreInfos = new ArrayList<>();
            for (int i = 0; i < years.size(); i++) {
                int num = random.nextInt(1000);
                System.out.println("用户：" + username + " " + years.get(i) + "年，消费：" + num + "元");
                userAggreInfos.add(new UserAggreInfo(years.get(i), num));
            }
            userConsumeInfo.setUserAggreInfos(userAggreInfos);
            partialResults.add(userConsumeInfo);
            try {
                System.out.println("用户：" + username + "到达barrier，等待其他用户。。。。。。");
                cyclicBarrier.await();
            } catch (InterruptedException e) {

            } catch (BrokenBarrierException e) {

            }
        }
    }

    class AggregatorThread implements Runnable {
        @Override
        public void run() {
            System.out.println("====统计用户消费消息===");
            int sum = 0;
            for (UserConsumeInfo user : partialResults) {
                int usersum = 0;
                String username = user.getUsername();
                System.out.println("用户：" + username + "消费信息如下");
                for (UserAggreInfo aggre : user.getUserAggreInfos()) {
                    System.out.print("\t" + aggre.getYear() + "年，消费" + aggre.getAmount() + "元" + "\t");
                    sum += aggre.getAmount();
                    usersum += aggre.getAmount();
                }
                System.out.print("\t" + "共消费" + usersum + "元" + "\t");
                System.out.println();
            }
            System.out.println("所有消费者消费总额" + sum);
        }
    }
}
